<script setup lang="ts">
  import Pagination from '@/components/Pagination/index.vue'
  import { ArrowDown } from '@element-plus/icons-vue'
  import FormModal from './FormModal.vue'
  import { h, ref } from 'vue'
  import {
    useGetAddressList,
    useAddressDisableByIds,
    useAddressDelByIds,
    useAddressEnableByIds,
  } from '../../services/useAddressList'
  import { ElDivider, ElMessageBox, TableInstance } from 'element-plus'
  import { HMessage, HMessageBox } from '@/components/common/message'

  const { list, listTotal, getListParam, getListLoading, getList } = useGetAddressList()
  const { disable } = useAddressDisableByIds()
  const { enable } = useAddressEnableByIds()
  const { del } = useAddressDelByIds()

  defineOptions({
    name: 'ReturnFactoryAddressList',
  })

  // 表单弹窗显示状态
  const formModalVisible = ref(false)

  // 地址选择列表
  const addressSelectList = ref<Array<ReturnFactoryAddress>>([])

  // 分页组件实例
  const paginationInstance = ref<InstanceType<typeof Pagination> | null>(null)

  // 正在编辑的地址id
  const editingAddressId = ref('')

  // 间距组件的间隔符
  const spacer = h(ElDivider, {
    direction: 'vertical',
    style: 'display: flex; align-items: center;',
  })

  // 表格组件实例
  const tableInstance = ref<TableInstance | null>(null)

  // 批量操作方法映射
  const multipleOperateFnMap = {
    del: del,
    enable: enable,
    disable: disable,
  }

  /**
   * 获取列表
   */
  const _getList = () => {
    if (paginationInstance.value) {
      getListParam.value.limit = paginationInstance.value.size
      getListParam.value.page = paginationInstance.value.current
      getList()
    }
  }

  /**
   * 表格删除按钮点击时触发
   * @param address - 地址对象
   */
  const handleDel = (address: ReturnFactoryAddress) => {
    if (addressSelectList.value.some((item) => item.defaultAddr)) {
      HMessageBox.error('不能删除默认地址')
      return
    }

    if (tableInstance.value) {
      tableInstance.value.toggleRowSelection(address, true)
      ElMessageBox({
        title: '提示',
        message: '确定删除该地址吗？',
        type: 'error',
        autofocus: false,
        showCancelButton: true,
        async beforeClose(action, instance, done) {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            instance.cancelButtonLoading = true
            const res = await del(addressSelectList.value.map((item) => item.id))
            instance.confirmButtonLoading = false
            instance.cancelButtonLoading = false
            if (res.code === 20000) {
              _getList()
              done()
              HMessage.success('删除成功')
              return
            }
            HMessageBox.error(res.message)
            return
          }

          done()
        },
      })
    }
  }

  /**
   * 地址选择事件
   * @param addressList - 地址选择列表
   */
  const handleSelectionChange = (addressList: Array<ReturnFactoryAddress>) => {
    addressSelectList.value = addressList
  }

  /**
   * 获取批量操作前的提示
   * @param type - 操作类型
   */
  const getMultipleOperateElMessageMsg = (type: 'del' | 'disable' | 'enable') => {
    if (type === 'del') {
      return '确定要删除选中的地址？'
    }

    if (type === 'enable') {
      return '确定要启用选中的地址？'
    }

    if (type === 'disable') {
      return '确定要禁用选中的地址？'
    }
  }

  /**
   * 获取批量操作成功后的提示
   * @param type - 操作类型
   */
  const getMultipleOperateSuccessMsg = (type: 'del' | 'disable' | 'enable') => {
    if (type === 'del') {
      return '删除成功'
    }

    if (type === 'enable') {
      return '启用成功'
    }

    if (type === 'disable') {
      return '禁用成功'
    }
  }

  /**
   * 批量操作
   * @param type - 操作类型
   */
  const handleMultipleOperate = (type: 'del' | 'disable' | 'enable') => {
    if (addressSelectList.value.some((item) => item.defaultAddr) && type === 'disable') {
      HMessageBox.error('不能禁用默认地址')
      return
    }

    if (addressSelectList.value.some((item) => item.defaultAddr) && type === 'del') {
      HMessageBox.error('不能删除默认地址')
      return
    }

    ElMessageBox({
      title: '提示',
      message: getMultipleOperateElMessageMsg(type),
      type: type === 'del' ? 'error' : 'warning',
      autofocus: false,
      showCancelButton: true,
      async beforeClose(action, instance, done) {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.cancelButtonLoading = true
          const res = await multipleOperateFnMap[type](
            addressSelectList.value.map((item) => item.id),
          )
          instance.confirmButtonLoading = false
          instance.cancelButtonLoading = false
          if (res.code === 20000) {
            HMessage.success(getMultipleOperateSuccessMsg(type))
            _getList()
            done()
            return
          }
          HMessageBox.error(res.message)
          return
        }

        done()
      },
    })
  }

  /**
   * 表格编辑按钮点击时触发
   * @param id - 地址id
   */
  const handleEdit = (id: string) => {
    editingAddressId.value = id
    formModalVisible.value = true
  }

  defineExpose({
    getList: _getList,
  })
</script>

<template>
  <div v-loading="getListLoading" class="address-list-container">
    <header class="header">
      <div class="btn-group">
        <h-plain-button @click="formModalVisible = true">添加地址</h-plain-button>
        <el-dropdown>
          <h-button :disabled="addressSelectList.length === 0">
            批量操作
            <el-icon>
              <arrow-down></arrow-down>
            </el-icon>
          </h-button>

          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="handleMultipleOperate('enable')">批量启用</el-dropdown-item>
              <el-dropdown-item @click="handleMultipleOperate('disable')"
                >批量禁用</el-dropdown-item
              >
              <el-dropdown-item @click="handleMultipleOperate('del')">批量删除</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
      <div class="search">
        <el-input
          v-model.trim="getListParam.keyword"
          placeholder="请输入关键字"
          clearable
          @keyup.enter="_getList"
          @clear="_getList"
        />
        <h-button type="primary" @click="_getList">
          <el-icon>
            <Search></Search>
          </el-icon>
          搜索
        </h-button>
      </div>
    </header>
    <main class="main">
      <el-table
        ref="tableInstance"
        :border="true"
        stripe
        height="100%"
        :data="list"
        @selection-change="handleSelectionChange"
      >
        <!-- 选择 -->
        <el-table-column type="selection" width="50" fixed="left" :align="'center'" />

        <!-- 序号 -->
        <el-table-column type="index" label="序号" width="50" :align="'center'" fixed="left" />

        <!-- 收货人姓名 -->
        <el-table-column label="收货人姓名" width="120" prop="username" show-overflow-tooltip />

        <!-- 收货人手机号 -->
        <el-table-column label="收货人手机号" width="120" prop="phone" show-overflow-tooltip />

        <!-- 收货人地址 -->
        <el-table-column
          label="收货人地址"
          min-width="200"
          prop="defaultAddr"
          show-overflow-tooltip
        >
          <template #default="{ row }">
            {{ [row.province, row.city, row.area, row.address].join('\xa0') }}
          </template>
        </el-table-column>

        <!-- 是否为默认地址 -->
        <el-table-column label="是否为默认地址" width="120" prop="defaultAddr">
          <template #default="{ row }">
            {{ row.defaultAddr ? '是' : '否' }}
          </template>
        </el-table-column>

        <!-- 创建时间 -->
        <el-table-column label="创建时间" width="140" prop="createTime" />

        <!-- 更新时间 -->
        <el-table-column label="更新时间" width="140" prop="updateTime" />

        <!-- 状态 -->
        <el-table-column label="状态" width="100" prop="status" fixed="right" :align="'center'">
          <template #default="{ row }">
            <div class="flex_justify_center">
              <h-status v-if="!row.status">启用</h-status>
              <h-status v-else type="info">禁用</h-status>
            </div>
          </template>
        </el-table-column>

        <!-- 操作 -->
        <el-table-column label="操作" width="100" prop="operate" fixed="right">
          <template #default="{ row }">
            <el-space :size="0" :spacer="spacer">
              <h-link @click="handleEdit(row.id)">编辑</h-link>
              <h-link type="error" @click="handleDel(row)">删除</h-link>
            </el-space>
          </template>
        </el-table-column>
      </el-table>
    </main>
    <footer class="footer">
      <pagination
        ref="paginationInstance"
        :list_total="listTotal"
        @size-change="_getList"
        @current-change="_getList"
      />
    </footer>

    <form-modal
      v-model:visible="formModalVisible"
      :address-id="editingAddressId"
      @update="_getList"
    />
  </div>
</template>

<style scoped lang="scss">
  .address-list-container {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: 12px;
    display: flex;
    flex-direction: column;
    row-gap: 5px;

    .header {
      display: flex;
      justify-content: space-between;

      .btn-group {
        display: flex;
        column-gap: 5px;
      }

      .search {
        display: flex;
        column-gap: 5px;
      }
    }

    .main {
      max-height: calc(100% - 66px);
    }

    .footer {
      display: flex;
      justify-content: flex-end;
    }
  }
</style>
